#pragma once


/*
 * HTTP packet parsing and forging
 */

#include <vector>
#include <string>
#include <map>


namespace bzbnet {


	enum class HTTPType {
		GET,
		HEAD,
		POST,
		PUT,
		DELETE,
		CONNECT,
		OPTIONS,
		TRACE,
		NONE
	};

	/*
	 * This structure holds both HTTP requests and responses
	 * If the packet is a response, <type> is set to HTTPType::NONE
	 * and <URI> is an empty string
	 * If the packet is a request, <status> is an empty string and <code> is zero
	 */

	struct HTTPPacket {

		HTTPType type;
		std::string URI;
		std::string status;
		unsigned int code;
		unsigned int version; // 11 for 1.1 or 20 for 2.0
		std::map<std::string, std::string> fields;
		std::string body;

		HTTPPacket(std::string str);

		HTTPPacket() {}

		std::string to_string();

		bool is_response() {
			return type == HTTPType::NONE;
		}

		bool is_request() {
			return type != HTTPType::NONE;
		}
		
	};


	/*
	 * Converts a packet's content to an HTTPPacket structure
	 */

	HTTPPacket parse_http_packet(std::string content);


	/*
	 * Convert an HTTPType constant to string
	 */
	inline std::string httptype_to_string(HTTPType type) {
		switch(type) {
			case HTTPType::GET: return "GET"; break;
			case HTTPType::HEAD: return "HEAD"; break;
			case HTTPType::POST: return "POST"; break;
			case HTTPType::PUT: return "PUT"; break;
			case HTTPType::DELETE: return "DELETE"; break;
			case HTTPType::CONNECT: return "CONNECT"; break;
			case HTTPType::OPTIONS: return "OPTIONS"; break;
			case HTTPType::TRACE: return "TRACE"; break;
			case HTTPType::NONE: return "NONE"; break;
			default: return ""; break;
		}
	}


}
